Skip to content

运维脚本示例:LNMP 部署与批量运维

版本提示:文中 Nginx 1.15.x、PHP 5.6 等已 EOL,仅作「旧教程脚本结构」参考;新环境请用发行版软件包或当前维护版本,并自行更新 ./configure 参数。

一、LNMP 一键编译部署(节选)

LNMP 指 Linux + Nginx + MySQL + PHP,常用于动态网站。下列脚本摘自教程示例:菜单安装 Nginx / PHP,并预留组合安装;注意:片段中 install_mysql 在 case 里被调用但未在摘录中定义,实际使用需补全该函数或改为 yum install mysql-server 等方案。

shell
#!/bin/bash
NGINX_V=1.15.6
PHP_V=5.6.36
TMP_DIR=/tmp

INSTALL_DIR=/usr/local

PWD_C=$PWD

echo
echo -e "\tMenu\n"
echo -e "1. Install Nginx"
echo -e "2. Install PHP"
echo -e "3. Install MySQL"
echo -e "4. Deploy LNMP"
echo -e "9. Quit"

function command_status_check() {
 if [ $? -ne 0 ]; then
  echo $1
  exit
 fi 
}

function install_nginx() {
    cd $TMP_DIR
    yum install -y gcc gcc-c++ make openssl-devel pcre-devel wget
    wget http://nginx.org/download/nginx-${NGINX_V}.tar.gz
    tar zxf nginx-${NGINX_V}.tar.gz
    cd nginx-${NGINX_V}
    ./configure --prefix=$INSTALL_DIR/nginx \
    --with-http_ssl_module \
    --with-http_stub_status_module \
    --with-stream
    command_status_check "Nginx - 平台环境检查失败!"
    make -j 4 
    command_status_check "Nginx - 编译失败!"
    make install
    command_status_check "Nginx - 安装失败!"
    mkdir -p $INSTALL_DIR/nginx/conf/vhost
    alias cp=cp ; cp -rf $PWD_C/nginx.conf $INSTALL_DIR/nginx/conf
    rm -rf $INSTALL_DIR/nginx/html/*
    echo "ok" > $INSTALL_DIR/nginx/html/status.html
    echo '<?php echo "ok"?>' > $INSTALL_DIR/nginx/html/status.php
    $INSTALL_DIR/nginx/sbin/nginx
    command_status_check "Nginx - 启动失败!"
}

function install_php() {
 cd $TMP_DIR
    yum install -y gcc gcc-c++ make gd-devel libxml2-devel \
        libcurl-devel libjpeg-devel libpng-devel openssl-devel \
        libmcrypt-devel libxslt-devel libtidy-devel
    wget http://docs.php.net/distributions/php-${PHP_V}.tar.gz
    tar zxf php-${PHP_V}.tar.gz
    cd php-${PHP_V}
    ./configure --prefix=$INSTALL_DIR/php \
    --with-config-file-path=$INSTALL_DIR/php/etc \
    --enable-fpm --enable-opcache \
    --with-mysql --with-mysqli --with-pdo-mysql \
    --with-openssl --with-zlib --with-curl --with-gd \
    --with-jpeg-dir --with-png-dir --with-freetype-dir \
    --enable-mbstring --enable-hash
    command_status_check "PHP - 平台环境检查失败!"
    make -j 4 
    command_status_check "PHP - 编译失败!"
    make install
    command_status_check "PHP - 安装失败!"
    cp php.ini-production $INSTALL_DIR/php/etc/php.ini
    cp sapi/fpm/php-fpm.conf $INSTALL_DIR/php/etc/php-fpm.conf
    cp sapi/fpm/init.d.php-fpm /etc/init.d/php-fpm
    chmod +x /etc/init.d/php-fpm
    /etc/init.d/php-fpm start
    command_status_check "PHP - 启动失败!"
}

read -p "请输入编号:" number
case $number in
    1)
        install_nginx;;
    2)
        install_php;;
    3)
        install_mysql;;
    4)
        install_nginx
        install_php
        ;;
    9)
        exit;;
esac

补充

  • PHP 5.6、Nginx 1.15 已较陈旧,新版本编译参数与依赖不同。
  • wget 官方 URL 需确认仍有效;内网环境需离线源码包。
  • 生产环境更常见 Docker / 包管理器安装 / Ansible,减少源码编译差异。

二、批量 SSH 执行命令(expect)

依赖 expect,从 host.infoIP、用户、端口、密码。密码明文存储风险极高,仅适合封闭实验网络;生产应用 SSH 密钥 + ssh-agentansibleTeleport

shell
#!/bin/bash
COMMAND=$*
HOST_INFO=host.info
for IP in $(awk '/^[^#]/{print $1}' $HOST_INFO); do
    USER=$(awk -v ip=$IP 'ip==$1{print $2}' $HOST_INFO)
    PORT=$(awk -v ip=$IP 'ip==$1{print $3}' $HOST_INFO)
    PASS=$(awk -v ip=$IP 'ip==$1{print $4}' $HOST_INFO)
    expect -c "
       spawn ssh -p $PORT $USER@$IP
       expect {
          \"(yes/no)\" {send \"yes\r\"; exp_continue}
          \"password:\" {send \"$PASS\r\"; exp_continue}
          \"$USER@*\" {send \"$COMMAND\r exit\r\"; exp_continue}
       }
    "
    echo "-------------------"
done

host.info 示例格式(需与 awk 字段对应):每行 IP 用户 端口 密码# 开头行为注释。


三、批量创建用户并写出口令文件

脚本中循环变量为 USER_LIST,却定义了 DATE=$@,若不加修改无法运行。典型修复方式之一:从文件读用户名列表。

shell
#!/bin/bash
USER_FILE=user.txt
USER_LIST=$(cat user.txt)   # 示例:一行一个用户名

for USER in $USER_LIST; do
    if ! id $USER &>/dev/null; then
        PASS=$(echo $RANDOM |md5sum |cut -c 1-8)
        useradd $USER
        echo $PASS |passwd --stdin $USER &>/dev/null
        echo "$USER   $PASS" >> $USER_FILE
        echo "$USER User create successful."
    else
        echo "$USER User already exists!"
    fi
done

补充passwd --stdin 多为 RHEL 系;Debian/Ubuntu 常用 chpasswd。明文密码落盘 极不安全,教学示例仅供参考。


四、批量检测网站 HTTP 状态

对 URL 列表最多测 3 次,成功则break;三次均失败则告警。

shell
#!/bin/bash  
URL_LIST="www.baidu.com www.ctnrs.com"
for URL in $URL_LIST; do
    FAIL_COUNT=0
    for ((i=1;i<=3;i++)); do
        HTTP_CODE=$(curl -o /dev/null --connect-timeout 3 -s -w "%{http_code}" $URL)
        if [ $HTTP_CODE -eq 200 ]; then
            echo "$URL OK"
            break
        else
            echo "$URL retry $FAIL_COUNT"
            let FAIL_COUNT++
        fi
    done
    if [ $FAIL_COUNT -eq 3 ]; then
        echo "Warning: $URL Access failure!"
    fi
done

补充:原逻辑在「第一次就 200」时 FAIL_COUNT 仍为 0,最后不会误报;若中途成功 break,也不会走到「等于 3」。若希望「重试次数」与日志一致,可单独用 i 计数或调整 FAIL_COUNT 更新时机。


五、小结

  • 批量运维优先 SSH 密钥配置管理,避免明文密码与交互 expect 长期运行。
  • 编译安装脚本适合学习依赖关系;线上尽量转向 受支持的发行版包或容器镜像